<script setup lang="ts">
import { computed, watch } from 'vue'
import { useVModel } from '@vueuse/core'  //
import { useCustomCountdown } from '@/hook/useCountDown'
import rules from '@/utils/rule'
import { requestToast } from '@/utils/requestToast'
import { mStyles } from '@/utils/useStyles'

// Props定义
interface Props {
  modelValue?: {
    phone: string
    sms_code: string
  }
  apiConfig?: {
    sendCodeApi?: string
    loginApi?: string
    type?: string
  }
  placeholder?: {
    phone?: string
    code?: string
  }
  buttonText?: {
    send?: string
    login?: string
  }
  codeLength?: number
  autoValidate?: boolean
}

const props = withDefaults(defineProps<Props>(), {
  modelValue: () => ({ phone: '', sms_code: '' }),
  apiConfig: () => ({ sendCodeApi: 'smsCode', loginApi: 'loginSms', type: 'phone' }),
  placeholder: () => ({ phone: '请输入你的手机号', code: '请输入你的验证码' }),
  buttonText: () => ({ send: '发送验证码', login: '验证并登录' }),
  codeLength: 6,
  autoValidate: true
})

// Emits定义
const emit = defineEmits<{
  'update:modelValue': [value: { phone: string; sms_code: string }]
  'sendCode': [phone: string]
  'login': [data: { phone: string; sms_code: string }]
  'validationChange': [valid: boolean]
}>()

// ✅ 用 useVModel 替代 formData
const formData = useVModel(props, 'modelValue', emit)

// 样式
const styles = mStyles

// 倒计时功能
const { remaining, startCountdown, counting } = useCustomCountdown({
  onCompleted: () => { counting.value = false }
})

// 计算属性
const canSendCode = computed(() => {
  if (!formData.value.phone) return false
  return rules.phone[1].pattern?.test(formData.value.phone) ?? false
})

const isValid = computed(() => {
  if (!props.autoValidate) return true
  const isPhoneValid = rules.phone[1].pattern?.test(formData.value.phone) ?? false
  const isCodeValid = formData.value.sms_code.trim().length > 0
  return isPhoneValid && isCodeValid
})

const sendButtonText = computed(() => props.buttonText?.send || '发送验证码')

// 方法
const handleSendCode = async () => {
  if (!canSendCode.value || counting.value) return

  try {
    const { status } = await requestToast(
      { phone: formData.value.phone },
      props.apiConfig.sendCodeApi || 'smsCode',
      '发送成功'
    )

    if (status) {
      startCountdown(60)
      emit('sendCode', formData.value.phone)
    }
  } catch (error) {
    console.error('发送验证码失败:', error)
  }
}

const handleLogin = async () => {
  if (!isValid.value) return
  emit('login', { ...formData.value })
}

// 监听校验变化
watch(isValid, (val) => {
  emit('validationChange', val)
})

// 暴露方法给父组件
defineExpose({
  formData,
  handleSendCode,
  handleLogin,
  isValid,
  canSendCode
})

</script>

<template>
  <div id="gr-phone-login">
    <van-cell-group>
      <!-- 手机号输入 -->
      <cVanfield v-model="formData.phone" placeholder="请输入你的手机号" label-width="10vmin" :rules="rules.phone" name="phone"
        clearable>
        <template #label>
          <p class="gr-label">
            <span class="text-[32px]">+86</span>
            <span class="gr-line"></span>
          </p>
        </template>
      </cVanfield>
    </van-cell-group>

    <van-cell-group class="mt-[40px]">
      <!-- 验证码输入 -->
      <cVanfield v-model="formData.sms_code" placeholder="请输入你的验证码" class="gr-code" :rules="rules.sms_code"
        name="sms_code" clearable>
        <template #button>
          <cButton iBgColor="translate" iPadding="0" :iColor="styles?.color1" iFontSize="3.6vmin"
            :disabled="counting || !canSendCode" @click="handleSendCode">
            {{ remaining > 0 ? `${remaining}s后重新发送` : sendButtonText }}
          </cButton>
        </template>
      </cVanfield>
    </van-cell-group>
  </div>
</template>

<style scoped lang="scss">
#gr-phone-login {
  width: 100%;

  .gr-label {
    display: flex;
    align-items: center;

    .gr-line {
      width: 2px;
      height: 32px;
      background: #3D3D3D1A;
      display: block;
      margin-left: 25px;
    }
  }

  .van-hairline--top-bottom:after {
    display: none;
  }

  .gr-code {
    padding: 0px 20px;
  }
}
</style>
